package com.songcan.gateway.configuration;


import com.songcan.gateway.converter.BearerAuthenticationConverter;
import com.songcan.gateway.converter.YfAuthenticationConverter;
import com.songcan.gateway.handle.AccessHandler;
import com.songcan.gateway.handle.AccessManager;
import com.songcan.gateway.handle.ReactiveRedisAuthenticationManager;
import com.songcan.gateway.point.YfHttpBasicServerAuthenticationEntryPoint;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.ReactiveAuthenticationManager;
import org.springframework.security.config.web.server.SecurityWebFiltersOrder;
import org.springframework.security.config.web.server.ServerHttpSecurity;
import org.springframework.security.oauth2.provider.token.store.redis.RedisTokenStore;
import org.springframework.security.web.server.SecurityWebFilterChain;
import org.springframework.security.web.server.authentication.AuthenticationWebFilter;
import org.springframework.security.web.server.authentication.ServerAuthenticationConverter;
import org.springframework.security.web.server.authentication.ServerHttpBasicAuthenticationConverter;

@Configuration
public class SecurityConfig {


    private RedisTemplate redisTemplate;
    private AccessManager accessManager;
    private BearerAuthenticationConverter bearerAuthenticationConverter;
    private AccessHandler accessHandler;

    @Autowired
    public SecurityConfig(RedisTemplate redisTemplate,AccessManager accessManager,BearerAuthenticationConverter bearerAuthenticationConverter,
                          AccessHandler accessHandler){
        this.redisTemplate = redisTemplate;
        this.accessHandler = accessHandler;
        this.bearerAuthenticationConverter = bearerAuthenticationConverter;
        this.accessManager = accessManager;
    }

    @Bean
    SecurityWebFilterChain webFluxSecurityFilterChain(ServerHttpSecurity http) {
        //token管理器
        ReactiveAuthenticationManager tokenAuthenticationManager = new ReactiveRedisAuthenticationManager(new RedisTokenStore(redisTemplate.getConnectionFactory()));
        //认证过滤器
        AuthenticationWebFilter authenticationWebFilter = new AuthenticationWebFilter(tokenAuthenticationManager);
         authenticationWebFilter.setServerAuthenticationConverter(new YfAuthenticationConverter(redisTemplate));

        http
                .httpBasic().disable()
                .csrf().disable()
                .authorizeExchange()
                .pathMatchers(HttpMethod.OPTIONS).permitAll()
                .anyExchange().access(accessManager)
                .and()
                .exceptionHandling()
                .authenticationEntryPoint(new YfHttpBasicServerAuthenticationEntryPoint())
                .and()
                .exceptionHandling()
                .accessDeniedHandler(accessHandler)
                .and()
                //oauth2认证过滤器
                .addFilterAt(authenticationWebFilter, SecurityWebFiltersOrder.AUTHENTICATION);
        return http.build();
    }
}



